package Waya::App;

use strict;
use warnings;
use Error ':try';

use Getopt::Long;
Getopt::Long::Configure('no_ignore_case');

our $VERSION = '0.1';

use base 'Waya::Base';

__PACKAGE__->mk_hash_accessors(qw(opt));


use constant GETOPT => (qw/
    help man log=s verbose|v+ quiet|q+ conf=s version|V
/);


sub usage {
    my $self = shift;
    require Pod::Usage;
    Pod::Usage::pod2usage(@_);
}


sub check_options {
    my $self = shift;

    usage(1) if $self->opt->{help};
    usage(-exitstatus => 0, -verbose => 2) if $self->opt->{man};

    if (my $conffile = $self->opt->{conf} ||= $ENV{SGF_CONF}) {
        # replace dollar-variables with their environment equivalent; useful
        # for $PROJROOT, for example
        open my $fh, $conffile or die "can't open $conffile: $!\n";
        my $yaml = do { local $/; <$fh> };
        close $fh or die "can't close $conffile: $!\n";

        $yaml =~ s/\$(\w+)/$ENV{$1} || "\$$1"/ge;

        require YAML;
        $self->opt(YAML::Load($yaml));
    }

    exit if $self->opt->{exit};
}


sub app_init {
    my $self = shift;

    my %opt;
    GetOptions(\%opt, $self->every_list('GETOPT')) or usage(2);

    $self->opt(\%opt);
    $self->check_options;
    $self->log->max_level(1 + ($opt{verbose} || 0) - ($opt{quiet} || 0));
    $self->log->filename($opt{log}) if defined $opt{log};
}


sub app_finish { 1 }
sub app_code   {}


sub run_app {
    my $self = shift;
    $self->app_init;

    $Error::Debug++;   # to get a stacktrace
    try {
        $self->app_code;
    } catch Error with {
        my $E = shift;
        $self->log->info("Application exception: $E");
        $self->log->info($E->stacktrace);
    };

    $self->app_finish;
}


1;
